package d7_tcp04;

import java.io.*;
import java.net.Socket;

public class ServerReaderThread extends Thread {
    //1、定义一个变量,接受主线程传过来的每一个客户端
    private Socket socket;

    //2、定义一个构造器,用于初始化上面的变量
    public ServerReaderThread(Socket socket) {
        this.socket = socket;
    }

    //3、重写run()方法,声明线程要进行的事情

    @Override
    public void run() {
        //8、捕获并处理异常,用作追踪下线处理
        try {
            //4、根据客户端对象socket,获取客户端的字节输入流
            InputStream is = socket.getInputStream();
            //5、将低级的字节输入流管道,包装成高级的特殊数据输入流管道
            DataInputStream dis = new DataInputStream(is);
            //7、由于要反复的读取,客户端发送来的数据,所以套死循环

            while (true) {
                //6、然后进行读取,客户端发送过来的数据
                String message = dis.readUTF();
                //8、展示上线的每个客户端的端口与ip地址发送了什么内容
                System.out.println(socket.getInetAddress().getHostAddress()
                        + ":" + socket.getPort() +"发送了" + message);
                System.out.println("--------------------------------------------");
                //9、将每一个客户端的消息发送给每一个客户端,包括它自己
                //参数肯定要将消息发传给方法(独立功能独立成方法)
                seedMessageToAll(message);
            }
        } catch (Exception e) {
            System.out.println(socket.getInetAddress().getHostAddress() + ":" +socket.getPort() +"下线了");

            //每当有一位socket下线了,就从集合中清除它
            Server01.allClientSocket.remove(socket);
        }

        //7、
    }

    /**
     * 把消息发给每一个socket
     * @param message
     */
    public void seedMessageToAll(String message) {
        //1、遍历所有的在线socket------->注意这是服务端的Socket,所以输出,会发送给与服务端连接的客户端
        for (Socket socket1 : Server01.allClientSocket) {
            //5、处理这个异常,注意不可以,跑上去,这个可能是管道的问题,不是追踪上下线
            try {
                //2、根据每一个Client的Socket,创建字节输出流
                OutputStream os = socket1.getOutputStream();
                //3、將低级的输出流管道包装成,高级的特殊数据输出流管道
                DataOutputStream dos = new DataOutputStream(os);

                //4、将每一位socket发送的消息,发送给每一位在线的socket,包括他自己
                dos.writeUTF(message);
                //5、进行刷新,不然可能有数据滞留
                dos.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
